import measuringPhaseEnum from "../enum/measuringPhase.enum"
import Data from "../object/Data"
import ObservableValue, { createObVal } from "../observer/observable.value"
import { createSubscription } from "../utils/Subscription"
export default class MeasurementModeData extends Data {
  protected _groups: any[]
  protected _groupMap: {}
  onDataChangedCallbacks: Set<Function>
  protected _editingGroupId: string
  protected _creatingGroupId: string
  phaseObservable: ObservableValue<number>
  selectedGroupIndexObservable: ObservableValue<number>
  pressProgressObservable: ObservableValue<number>
  pointPositionObservable: ObservableValue<THREE.Vector3>
  constructor() {
    super(...arguments)
    this.name = "measure-mode"
    this._groups = []
    this._groupMap = {}
    this.onDataChangedCallbacks = new Set()
    this._editingGroupId = null
    this._creatingGroupId = null
    this.phaseObservable = createObVal(measuringPhaseEnum.CLOSED)
    this.selectedGroupIndexObservable = new ObservableValue(-1)
    this.pressProgressObservable = new ObservableValue(-1)
    this.pointPositionObservable = new ObservableValue(null)
  }
  modeActive() {
    return this.phase !== measuringPhaseEnum.CLOSED
  }
  *groups() {
    for (const e of this._groups) yield e
  }
  get selectedGroupSid() {
    const e = this.selectedGroupInfo
    return e && e.info.sid ? e.info.sid : null
  }
  get selectedGroupInfo() {
    return -1 === this.selectedGroupIndex ? null : this.getGroupInfo(this.selectedGroupIndex)
  }
  get phase() {
    return this.phaseObservable.value
  }
  get creatingGroupId() {
    return this._creatingGroupId
  }
  set creatingGroupId(e) {
    this._creatingGroupId = e
  }
  get editingGroupId() {
    return this._editingGroupId
  }
  set editingGroupId(e) {
    this._editingGroupId = e
  }
  setPhase(e: number) {
    this.phase !== e && (this.phaseObservable.value = e)
  }
  onPhaseChanged(e: any) {
    return this.phaseObservable.onChanged(e)
  }
  notifyDataChanged() {
    this.onDataChangedCallbacks.forEach(e => e())
  }
  onDataChanged(e) {
    return createSubscription(
      () => this.onDataChangedCallbacks.add(e),
      () => this.onDataChangedCallbacks.delete(e),
      !0
    )
  }
  get groupCount() {
    return this._groups.length
  }
  get selectedGroupIndex() {
    return this.selectedGroupIndexObservable.value
  }
  setSelectedGroupIndex(e: number) {
    this.selectedGroupIndexObservable.value = e
  }
  onSelectedGroupIndexChanged(e) {
    return this.selectedGroupIndexObservable.onChanged(e)
  }
  get pointPosition() {
    return this.pointPositionObservable.value
  }
  setPointPosition(e) {
    this.pointPositionObservable.value = e
  }
  onPointPositionChanged(e) {
    return this.pointPositionObservable.onChanged(e)
  }
  setPressProgress(e) {
    this.pressProgressObservable.value = e
  }
  get pressProgress() {
    return this.pressProgressObservable.value
  }
  onPressProgressChanged(e) {
    return this.pressProgressObservable.onChanged(e)
  }
  getGroupInfo(e) {
    return e < 0 || e >= this._groups.length ? null : this._groups[e]
  }
  getGroupInfoBySid(e) {
    return e ? this._groupMap[e] : null
  }
  repopulate(e) {
    this.clear()
    for (const t of e) {
      const e = t.clone()
      this._groups.push(e), (this._groupMap[t.info.sid] = e)
    }
    ;(this.editingGroupId || this.creatingGroupId) && this.notifyDataChanged()
  }
  clear() {
    this._groups = []
    this._groupMap = {}
  }
}
